/*
 * Project: yygh-parent
 *
 * File Created at 2023/7/16
 *
 * 自定义时间格式代替DATE标签：2023-07-16 18:26:18:26
 */
package com.atguigu.yygh.order.service.impl;

import com.alibaba.fastjson.JSONObject;


import com.atguigu.yygh.common.exception.HospitalException;
import com.atguigu.yygh.common.result.ResultCodeEnum;
import com.atguigu.yygh.order.mapper.HospitalSetMapper;
import com.atguigu.yygh.model.hosp.Department;
import com.atguigu.yygh.model.hosp.HospitalSet;
import com.atguigu.yygh.model.hosp.Schedule;
import com.atguigu.yygh.repository.DepartmentRepository;
import com.atguigu.yygh.repository.ScheduleRepository;
import com.atguigu.yygh.order.service.ScheduleService;
import com.atguigu.yygh.vo.hosp.BookingScheduleRuleVo;
import com.atguigu.yygh.vo.hosp.ScheduleOrderVo;
import com.atguigu.yygh.vo.hosp.ScheduleQueryVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @author 用户名
 * @Type ScheduleServiceImpl.java
 * @Desc
 * @date 2023/7/16 18:26
 */
@Service
@Slf4j
public class ScheduleServiceImpl implements ScheduleService {
    @Autowired
    ScheduleRepository scheduleRepository;
    @Autowired
    HospitalSetMapper hospitalSetMapper;
    @Autowired
    DepartmentRepository departmentRepository;



        @Override
    public void saveSchedule(Map paramMap) {
        log.info(JSONObject.toJSONString(paramMap));
            String hosScheduleId=(String)paramMap.get("hosScheduleId");
            if(StringUtils.isEmpty(hosScheduleId)){
                throw new HospitalException(ResultCodeEnum.PARAM_ERROR);
            }
            Schedule schedule = JSONObject.parseObject(JSONObject.toJSONString(paramMap), Schedule.class);
            Schedule target = scheduleRepository.getScheduleByHosScheduleId(hosScheduleId);

            if(null!=target){

                target.setStatus(0);
                target.setCreateTime(new Date());
                target.setUpdateTime(new Date());
                target.setIsDeleted(0);
                scheduleRepository.save(target);
            }else{

                schedule.setStatus(0);
                schedule.setCreateTime(new Date());
                schedule.setUpdateTime(new Date());
                schedule.setIsDeleted(0);
                scheduleRepository.save(schedule);
            }

        }


    @Override
    public Page<Schedule> selectPage(Integer page, Integer limit, ScheduleQueryVo scheduleQueryVo) {
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
//0为第一页
        Pageable pageable = PageRequest.of(page-1, limit, sort);
        Schedule schedule = new Schedule();
        BeanUtils.copyProperties(scheduleQueryVo,schedule);
        //创建匹配器，即如何使用查询条件
        ExampleMatcher matcher = ExampleMatcher.matching() //构建对象
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) //改变默认字符串匹配方式：模糊查询
                .withIgnoreCase(true); //改变默认大小写忽略方式：忽略大小写
        //创建实例
        Example<Schedule> example = Example.of(schedule, matcher);

        Page<Schedule> pages = scheduleRepository.findAll(example,pageable);

        return pages;
    }

    @Override
    public void removeByHoscodeAndHosScheduleId(ScheduleQueryVo scheduleQueryVo) {

        Schedule schedule = new Schedule();
        BeanUtils.copyProperties(scheduleQueryVo,schedule);
        Schedule schedule1 = scheduleRepository.findScheduleByHoscodeAndHosScheduleId(schedule.getHoscode(),schedule.getDepcode());
        if(schedule1!=null){
            scheduleRepository.deleteById(schedule1.getId());
        }
    }

    @Override
    public Map<String,Object> selectPageByHoscodeAndDepcode(Integer page, Integer limit, String hoscode, String depcode) {
        //最终期望的结果
        List<BookingScheduleRuleVo> result=new ArrayList<>();
        //分页后的结果
        List<BookingScheduleRuleVo> result2=new ArrayList<>();
        List<Schedule> procession=new ArrayList<>();
        Map<String,Object> map=new HashMap<>();
        //1.先得到这个科室的所有数据
        //在这里排序后面数据还是会变成无序
        List<Schedule> schedules= scheduleRepository.findScheduleByHoscodeAndDepcodeOrderByWorkDateDesc(hoscode,depcode);
        //2.进行分组
        Map<Date, List<Schedule>> collect = schedules.stream().collect(Collectors.groupingBy(Schedule::getWorkDate));
        collect.forEach((date,list)->{
            //3.对分组的数据加入list
//            list.forEach((item)->{
//                procession.add(item);
//            });
            AtomicReference<Integer> canBookNumber= new AtomicReference<>(0);
            AtomicReference<Integer> bookedNumber= new AtomicReference<>(0);
            BookingScheduleRuleVo bookingScheduleRuleVo = new BookingScheduleRuleVo();
            //4.对分组的数据累加统计得到 可预约人数和已预约人数
            list.forEach((item)->{
                    bookedNumber.updateAndGet(v -> v + item.getAvailableNumber());
                    canBookNumber.updateAndGet(v -> v + item.getReservedNumber());

            });
            Date workDate = list.get(0).getWorkDate();
            DateTime dateTime = new DateTime(workDate);
            String dayOfWeek = this.getDayOfWeek(dateTime);
            bookingScheduleRuleVo.setDayOfWeek(dayOfWeek);
            bookingScheduleRuleVo.setReservedNumber(bookedNumber.get());
            bookingScheduleRuleVo.setAvailableNumber(canBookNumber.get());
            bookingScheduleRuleVo.setWorkDate(workDate);
            result.add(bookingScheduleRuleVo);
        });
        //5.必须对结果进行排序
        List<BookingScheduleRuleVo> studentsSortDesc = result.stream().sorted(Comparator.comparing(BookingScheduleRuleVo::getWorkDate).reversed()).collect(Collectors.toList());

        //6.对list进行分页

        //创建匹配器，即如何使用查询条件
        //创建实例
//        Example<Schedule> example = Example.of(schedule);


//        int totalPages = (pages.getTotalPages())/limit;
        int totalPages = studentsSortDesc.size();
        int start=(page-1)*limit;
        for (int i=start;i<start+4;i++){
            if(i>totalPages-1){
                break;
            }
            BookingScheduleRuleVo bookingScheduleRuleVo = studentsSortDesc.get(i);
            result2.add(bookingScheduleRuleVo);
        }





//        //extro 可以预约的数量


        map.put("total",totalPages);
        map.put("list",result2);




//        List<BookingScheduleRuleVo> result=new ArrayList<>();
//        for (Schedule page1 : pages) {
//            Date date = page1.getWorkDate();
//
//            String dayOfWeek = this.getDayOfWeek(dateTime);
//            BookingScheduleRuleVo bookingScheduleRuleVo = new BookingScheduleRuleVo();
//            bookingScheduleRuleVo.setDayOfWeek(dateTime.getYear()+"-"+dateTime.getMonthOfYear()+"-"+dateTime.getDayOfYear()+dayOfWeek);
//            //可预约数量是由当天查询统计出来的
//            bookingScheduleRuleVo.setAvailableNumber(page1.getAvailableNumber());
//
//

//        }

        return map;
    }

    @Override
    public List<Schedule> getDetailSchedule(String hoscode, String depcode, String workDate) {
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
//0为第一页
        List<Schedule> schedules=scheduleRepository.findScheduleByHoscodeAndDepcodeAndWorkDate(hoscode,depcode,new DateTime(workDate).toDate());


        return schedules;
    }

    @Override
    public Schedule getById(String scheduleId) {
        Schedule schedule = scheduleRepository.findById(scheduleId).get();
        this.packSchedule(schedule);
        return schedule;
    }

    //根据排班id获取预约下单数据
    @Override
    public ScheduleOrderVo getScheduleOrderVo(String scheduleId) {


        return null;
    }

    @Override
    public void saveSchedule(Schedule schedule) {
        scheduleRepository.save(schedule);
    }

    public void packSchedule(Schedule schedule){
        String hoscode = schedule.getHoscode();
        String depcode = schedule.getDepcode();
        QueryWrapper<HospitalSet> queryWrapper1=new QueryWrapper<>();
        queryWrapper1.eq("hoscode",schedule.getHoscode());
        com.atguigu.yygh.model.hosp.HospitalSet hospitalSet = hospitalSetMapper.selectOne(queryWrapper1);
        Map<String, Object> param = schedule.getParam();
        param.put("hosname",hospitalSet.getHosname());
        Department department = departmentRepository.findDepartmentByHoscodeAndDepcode(hoscode, depcode);
        param.put("depname",department.getDepname());
        //TODO

    }


    /**
     * 根据日期获取周几数据
     * @param dateTime
     * @return
     */
    private String getDayOfWeek(DateTime dateTime) {
        String dayOfWeek = "";
        switch (dateTime.getDayOfWeek()) {
            case DateTimeConstants.SUNDAY:
                dayOfWeek = "周日";
                break;
            case DateTimeConstants.MONDAY:
                dayOfWeek = "周一";
                break;
            case DateTimeConstants.TUESDAY:
                dayOfWeek = "周二";
                break;
            case DateTimeConstants.WEDNESDAY:
                dayOfWeek = "周三";
                break;
            case DateTimeConstants.THURSDAY:
                dayOfWeek = "周四";
                break;
            case DateTimeConstants.FRIDAY:
                dayOfWeek = "周五";
                break;
            case DateTimeConstants.SATURDAY:
                dayOfWeek = "周六";
            default:
                break;
        }
        return dayOfWeek;
    }


}


/**
 * Revision history
 * -------------------------------------------------------------------------
 * <p>
 * Date Author Note
 * -------------------------------------------------------------------------
 * 2023/7/16 用户名 create
 */ 
